#include <stdio.h>
#include <mpi.h>
const int num_steps = 2E9;

int main(int ac, char **av){

    double step = 1.0L / num_steps;
    char message[100];
    double res, start, end;
    int myid, numprocess;
    double pi = 0.0;
    MPI_Status status;
    MPI_Init(&ac, &av);
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocess);
    if (numprocess == 1){
        fprintf(stderr, "World size must bigger than one for %s\n", av[0]);
        MPI_Abort(MPI_COMM_WORLD, 1);
    }
    int chunk = num_steps / (numprocess - 1);

    // printf("I am %d \n", myid);
    if(myid == 0){//主进程
        start = MPI_Wtime();
        for(int i = 1; i < numprocess; i++){
            MPI_Recv(&res, sizeof(res), MPI_DOUBLE, i, 99, MPI_COMM_WORLD, &status);
            // printf("res = %lf\n", res);
            pi += res * step;
        }
        end = MPI_Wtime();

        printf("%.20lf\n", pi);
        printf("Size = %d, rank = %d, time = %f \n", numprocess, myid,  (end - start));
    }else{
        double sum = 0.0;
        for(int i = (myid - 1) * chunk; i < myid * chunk; i++){
            // printf("%d ", i);
            double x = (i + 0.5) * step;
            sum += 4.0L / (1.0L + x * x);
        }
        MPI_Send(&sum, sizeof(sum), MPI_DOUBLE, 0, 99, MPI_COMM_WORLD);
    }
    
    MPI_Finalize();
}

